/**
 * @Created Oct 8, 2010 4:52:40 PM
 * @author cry30
 */
package com.philip.journal.common;

import java.util.ArrayList;
import java.util.List;

import com.philip.journal.core.Messages.Error;

/**
 *
 */
public final class CollectionUtils {

    /** Singleton instance reference. */
    private static final CollectionUtils INSTANCE = new CollectionUtils();

    /** Prevent extension. */
    private CollectionUtils() {}

    /**
     * Singleton factory method.
     * 
     * @return Singleton instance of this class.
     */
    public static CollectionUtils getInstance() {
        return INSTANCE;
    }

    /**
     * Down casts a given List to a typed List.
     * 
     * @param <T> specific type of the List.
     * @param list List to be down casted.
     * @return the down casted List of <T>
     * 
     * @exception IllegalArgumentException when the list parameter is null.
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> convertList(final List<?> list) {
        if (list == null) {
            throw new IllegalArgumentException(Error.IAE_NULL);
        }

        final List<T> retval = new ArrayList<T>();
        for (final Object object : list) {
            retval.add((T) object);
        }
        return retval;
    }

    /**
     * Compares the contents of 2 unordered List.
     * 
     * @param list1 List 1 to be compared to List 2.
     * @param list2 List 2 to be compared to List 1.
     * @return true when
     * @throws NullPointerException when one of the elements in either List is null. This may not throw when an
     *             inequality has been met early on.
     */
    public static boolean equals(final List<?> list1, final List<?> list2) {
        boolean retval = true;
        if (list1 == list2) { // NOPMD by r39 on 3/30/11 10:38 AM
            retval = true;
        } else if (list1 == null && list2 != null) {
            retval = false;
        } else if (list2 == null && list1 != null) {
            retval = false;
        } else if (list1 != null && list1.size() != list2.size()) { // NOPMD by r39
            retval = false;
        } else {
            retval = compareList(list1, list2);
        }
        return retval;
    }

    /**
     * Helper method to compare the contents of list1 and list2.
     * 
     * @param list1 List 1 to be compared to List 2.
     * @param list2 List 2 to be compared to List 1.
     * @return true of the contents of list1 is identical to contents of list2.
     */
    private static boolean compareList(final List<?> list1, final List<?> list2) {
        boolean retval = true;
        for (final Object firstIter : list1) {
            boolean matched = false;
            for (final Object secondIter : list2) {
                // toString to force NPE as defined in javadoc
                if (firstIter.toString().equals(secondIter.toString())) {
                    matched = true;
                    break;
                }
            }
            if (!matched) {
                retval = false;
                break;
            }
        }
        return retval;
    }
}
